package arkham.data;

import java.util.ArrayList;
import java.util.List;

import arkham.data.Globals.EffectUsage;
import arkham.data.Investigator.InvestigatorPower;
import arkham.jaxb.encounter.CostType;

/**
 * This abstract Effect class represents the type of Mod effects and Usable effects.
 * It contains generic methods pertaining to usage and cost
 * @author ctheng
 *
 */
public abstract class Effect
{
    protected EffectUsage usage;
    protected List<CostType> extraCosts;
    protected EffectSource source;

    protected Effect()
    {
        extraCosts = new ArrayList<CostType>();
    }

    /**
     * Gets the usage type of this effect
     * @return the usage of this effect
     */
    public EffectUsage getUsage() {
        return usage;
    }

    /**
     * Returns true if this effect requires a spell successfully cast
     * @return true if this effect is from a spell
     */
    public boolean requiresCast()
    {
        return usage.equals(EffectUsage.CAST_AND_DISCARD)
            || usage.equals(EffectUsage.CAST_AND_EXHAUST);
    }

    /**
     * Sets the usage type of this effect
     * @param usage the usage to set
     */
    public void setUsage(EffectUsage usage)
    {
        this.usage = usage;
    }

    /**
     * Gets the additional costs of using this effect
     * @return the list of additional costs
     */
    public List<CostType> getExtraCosts() {
        return extraCosts;
    }

    /**
     * Sets the source of the effect
     * @param source the source to set
     */
    public void setSource(EffectSource source) {
        this.source = source;
    }

    /**
     * Gets the source of the effect
     * @return the source of the effect
     */
    public EffectSource getSource() {
        return source;
    }

    /**
     * Returns a string identifying the source of the effect
     * Investigator powers are defined by their names
     * Personal effects are defined by a % before their names
     * Investigator cards are defined by # before their id
     * @return the source string
     */
    public String getSourceString()
    {
        return source.getIdentifier();
    }

    /**
     * Gets the string representation of the effect for transmission over
     * the network
     * @return the string representation of the effect
     */
    public abstract String getIdentifier();

    /**
     * Checks if this effect is unavailable because its source is exhausted
     * @return true if this effect is unavailable because it is exhausted
     */
    public boolean isExhausted()
    {
        return (usage.equals(EffectUsage.CAST_AND_EXHAUST) || usage.equals(EffectUsage.EXHAUST)) &&
                source.isExhausted();
    }

}
